<template>
  <div class="pagination-wrapper">
    <!-- 扩展功能气泡框 -->
    <Transition name="popup">
      <div v-if="showMoreOptions" class="more-options-popup">
        <div class="popup-content">
          <!-- 快速跳转 -->
          <div class="option-group">
            <label class="option-label">跳转至</label>
            <div class="jump-controls">
              <input
                ref="jumpInput"
                v-model.number="jumpPage"
                type="number"
                :min="1"
                :max="totalPages"
                @keyup.enter="handleJump"
                class="jump-input"
                :placeholder="`1-${totalPages}`"
              />
              <button class="action-btn" @click="handleJump">跳转</button>
            </div>
          </div>

          <!-- 每页条数 -->
          <div class="option-group">
            <label class="option-label">每页显示</label>
            <div class="size-controls">
              <button
                v-for="size in pageSizeOptions"
                :key="size"
                class="size-btn"
                :class="{ active: size === currentPageSize }"
                @click="handleSizeChange(size)"
              >
                {{ size }}
              </button>
            </div>
          </div>

          <!-- 快捷跳转 -->
          <div class="option-group">
            <label class="option-label">快捷跳转</label>
            <div class="quick-nav">
              <button class="quick-btn" :disabled="currentPage === 1" @click="goToPage(1)">
                首页
              </button>
              <button
                class="quick-btn"
                :disabled="currentPage === totalPages"
                @click="goToPage(totalPages)"
              >
                末页
              </button>
            </div>
          </div>

          <!-- 统计信息 -->
          <div class="stats-info">
            <div class="stat-item">
              <span class="stat-label">总共</span>
              <span class="stat-value">{{ total }}</span>
              <span class="stat-unit">条记录</span>
            </div>
            <div v-if="currentRangeEnd > 0" class="stat-item">
              <span class="stat-label">当前显示</span>
              <span class="stat-value">{{ currentRangeStart }}-{{ currentRangeEnd }}</span>
              <span class="stat-unit">条</span>
            </div>
          </div>
        </div>

        <!-- 关闭按钮 -->
        <button class="close-btn" @click="showMoreOptions = false">
          <svg viewBox="0 0 24 24" class="close-icon">
            <line x1="18" y1="6" x2="6" y2="18"></line>
            <line x1="6" y1="6" x2="18" y2="18"></line>
          </svg>
        </button>
      </div>
    </Transition>

    <!-- 基础分页控制 -->
    <div class="pagination-basic">
      <!-- 上一页 -->
      <button
        class="pagination-btn prev-btn"
        :disabled="currentPage === 1"
        @click="goToPage(currentPage - 1)"
        title="上一页"
      >
        <svg viewBox="0 0 24 24" class="btn-icon">
          <path d="M15 18l-6-6 6-6" />
        </svg>
      </button>

      <!-- 页码显示区域 -->
      <div class="pages-container">
        <template v-for="page in visiblePages" :key="page">
          <button
            v-if="page !== '...'"
            class="pagination-btn page-btn"
            :class="{ active: page === currentPage }"
            @click="goToPage(page as number)"
          >
            {{ page }}
          </button>
          <span v-else class="ellipsis">...</span>
        </template>
      </div>

      <!-- 下一页 -->
      <button
        class="pagination-btn next-btn"
        :disabled="currentPage === totalPages"
        @click="goToPage(currentPage + 1)"
        title="下一页"
      >
        <svg viewBox="0 0 24 24" class="btn-icon">
          <path d="M9 18l6-6-6-6" />
        </svg>
      </button>

      <!-- 页面信息 -->
      <div class="page-info">{{ currentPage }} / {{ totalPages }}</div>

      <!-- 更多功能触发按钮 -->
      <button
        class="more-btn"
        @click="toggleMoreOptions"
        :class="{ active: showMoreOptions }"
        title="更多选项"
      >
        <svg viewBox="0 0 24 24" class="more-icon">
          <path d="M7 10l5 5 5-5" />
        </svg>
      </button>
    </div>

    <!-- 背景遮罩 -->
    <div
      v-if="showMask && showMoreOptions"
      class="popup-overlay"
      @click="showMoreOptions = false"
    ></div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, watch, nextTick } from 'vue';

// 定义组件属性类型
interface PaginationProps {
  total: number;
  pageSize?: number;
  currentPage?: number;
  pageSizeOptions?: number[];
  maxVisiblePages?: number;
  showMask?: boolean;
}

// 定义事件类型
interface PaginationEmits {
  (e: 'update:currentPage', page: number): void;
  (e: 'update:pageSize', size: number): void;
  (e: 'change', page: number, size: number): void;
}

// 属性默认值
const props = withDefaults(defineProps<PaginationProps>(), {
  pageSize: 10,
  currentPage: 1,
  pageSizeOptions: () => [10, 20, 50, 100],
  maxVisiblePages: 5,
  showMask: true
});

// 事件定义
const emit = defineEmits<PaginationEmits>();

// 响应式数据
const showMoreOptions = ref(false);
const jumpPage = ref<number>(props.currentPage);
const currentPageSize = ref(props.pageSize);
const jumpInput = ref<HTMLInputElement>();

// 计算属性
const totalPages = computed(() => Math.ceil(props.total / currentPageSize.value));

// 当前页显示的数据范围
const currentRangeStart = computed(() => {
  return (props.currentPage - 1) * currentPageSize.value + 1;
});

const currentRangeEnd = computed(() => {
  const end = props.currentPage * currentPageSize.value;
  return Math.min(end, props.total);
});

// 计算可见页码（简化版本，适合小屏幕）
const visiblePages = computed(() => {
  const pages: (number | string)[] = [];
  const maxVisible = props.maxVisiblePages;
  const current = props.currentPage;
  const total = totalPages.value;

  if (total <= maxVisible) {
    for (let i = 1; i <= total; i++) {
      pages.push(i);
    }
  } else {
    const sidePages = Math.floor((maxVisible - 1) / 2);
    let start = Math.max(1, current - sidePages);
    let end = Math.min(total, current + sidePages);

    // 调整范围确保显示足够的页码
    if (end - start + 1 < maxVisible) {
      if (start === 1) {
        end = Math.min(total, start + maxVisible - 1);
      } else {
        start = Math.max(1, end - maxVisible + 1);
      }
    }

    // 添加省略号逻辑
    if (start > 1) {
      pages.push(1);
      if (start > 2) pages.push('...');
    }

    for (let i = start; i <= end; i++) {
      pages.push(i);
    }

    if (end < total) {
      if (end < total - 1) pages.push('...');
      pages.push(total);
    }
  }

  return pages;
});

// 方法
const goToPage = (page: number) => {
  if (page < 1 || page > totalPages.value || page === props.currentPage) {
    return;
  }

  emit('update:currentPage', page);
  emit('change', page, currentPageSize.value);

  // 页面切换后关闭弹窗
  showMoreOptions.value = false;
};

const toggleMoreOptions = async () => {
  showMoreOptions.value = !showMoreOptions.value;

  if (showMoreOptions.value) {
    await nextTick();
    jumpInput.value?.focus();
  }
};

const handleJump = () => {
  if (jumpPage.value && jumpPage.value >= 1 && jumpPage.value <= totalPages.value) {
    goToPage(jumpPage.value);
  }
};

const handleSizeChange = (size: number) => {
  currentPageSize.value = size;
  emit('update:pageSize', size);
  emit('update:currentPage', 1);
  emit('change', 1, size);

  // 关闭弹窗
  showMoreOptions.value = false;
};

// 监听器
watch(
  () => props.currentPage,
  (newPage) => {
    jumpPage.value = newPage;
  }
);

watch(
  () => props.pageSize,
  (newSize) => {
    currentPageSize.value = newSize;
  }
);

// 点击外部关闭弹窗
const handleClickOutside = (e: Event) => {
  const target = e.target as Element;
  if (!target.closest('.pagination-wrapper')) {
    showMoreOptions.value = false;
  }
};

// 监听ESC键关闭弹窗
const handleKeyDown = (e: KeyboardEvent) => {
  if (e.key === 'Escape') {
    showMoreOptions.value = false;
  }
};

// 生命周期
import { onMounted, onUnmounted } from 'vue';

onMounted(() => {
  document.addEventListener('click', handleClickOutside);
  document.addEventListener('keydown', handleKeyDown);
});

onUnmounted(() => {
  document.removeEventListener('click', handleClickOutside);
  document.removeEventListener('keydown', handleKeyDown);
});
</script>

<style scoped>
.pagination-wrapper {
  position: relative;
  display: inline-block;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* 基础分页控制 */
.pagination-basic {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  transition: all 0.2s ease;
}

.pagination-basic:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

/* 分页按钮 */
.pagination-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 32px;
  height: 32px;
  border: none;
  background: transparent;
  color: #6b7280;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.2s ease;
  font-size: 12px;
  font-weight: 500;
}

.pagination-btn:hover:not(:disabled) {
  background: #f3f4f6;
  color: #374151;
}

.pagination-btn:disabled {
  color: #d1d5db;
  cursor: not-allowed;
}

.pagination-btn.active {
  background: #3b82f6;
  color: white;
}

.btn-icon {
  width: 16px;
  height: 16px;
  stroke: currentColor;
  stroke-width: 2;
  fill: none;
}

/* 页码容器 */
.pages-container {
  display: flex;
  align-items: center;
  gap: 2px;
}

.page-btn {
  min-width: 32px;
  font-variant-numeric: tabular-nums;
}

.ellipsis {
  padding: 0 4px;
  color: #9ca3af;
  font-size: 12px;
}

/* 页面信息 */
.page-info {
  font-size: 13px;
  color: #6b7280;
  margin-left: 8px;
  font-variant-numeric: tabular-nums;
  min-width: 40px;
  text-align: center;
}

/* 更多按钮 */
.more-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: none;
  background: transparent;
  color: #9ca3af;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s ease;
  margin-left: 4px;
}

.more-btn:hover {
  background: #f3f4f6;
  color: #6b7280;
}

.more-btn.active {
  background: #3b82f6;
  color: white;
  transform: rotate(180deg);
}

.more-icon {
  width: 16px;
  height: 16px;
  stroke: currentColor;
  stroke-width: 2;
  fill: none;
  transition: transform 0.2s ease;
}

/* 弹出框 */
.more-options-popup {
  position: absolute;
  right: 0;
  bottom: 40px;
  z-index: 1000;
  min-width: 280px;
  background: white;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
  overflow: hidden;
}

.popup-content {
  padding: 20px;
}

.close-btn {
  position: absolute;
  top: 7px;
  right: 7px;
  width: 24px;
  height: 24px;
  border: none;
  background: transparent;
  color: #9ca3af;
  border-radius: 4px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
}

.close-btn:hover {
  background: #f3f4f6;
  color: #6b7280;
}

.close-icon {
  width: 14px;
  height: 14px;
  stroke: currentColor;
  stroke-width: 2;
}

/* 选项组 */
.option-group {
  margin-bottom: 20px;
}

.option-group:last-child {
  margin-bottom: 0;
}

.option-label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: #374151;
  margin-bottom: 8px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* 跳转控制 */
.jump-controls {
  display: flex;
  gap: 8px;
  align-items: center;
}

.jump-input {
  flex: 1;
  height: 28px;
  padding: 0 12px;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  font-size: 12px;
  transition: all 0.2s ease;
}

.jump-input:focus {
  outline: none;
  border-color: #3b82f6;
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

.action-btn {
  height: 28px;
  padding: 0 12px;
  background: #3b82f6;
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
}

.action-btn:hover {
  background: #2563eb;
}

/* 页面大小控制 */
.size-controls {
  display: flex;
  gap: 4px;
  align-items: center;
  flex-wrap: wrap;
}

.size-btn {
  height: 27px;
  padding: 0 11px;
  border: 1px solid #e5e7eb;
  background: white;
  color: #6b7280;
  border-radius: 6px;
  font-size: 12px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.size-btn:hover {
  border-color: #3b82f6;
  color: #3b82f6;
}

.size-btn.active {
  background: #3b82f6;
  border-color: #3b82f6;
  color: white;
}

/* 快捷导航 */
.quick-nav {
  display: flex;
  gap: 8px;
}

.quick-btn {
  height: 27px;
  padding: 0 10px;
  border: 1px solid #e5e7eb;
  background: white;
  color: #6b7280;
  border-radius: 6px;
  font-size: 12px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.quick-btn:hover:not(:disabled) {
  border-color: #3b82f6;
  color: #3b82f6;
}

.quick-btn:disabled {
  color: #d1d5db;
  cursor: not-allowed;
}

/* 统计信息 */
.stats-info {
  background: #f9fafb;
  border-radius: 8px;
  padding: 12px;
  margin-top: 16px;
}

.stat-item {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  margin-bottom: 4px;
}

.stat-item:last-child {
  margin-bottom: 0;
}

.stat-label {
  color: #6b7280;
}

.stat-value {
  color: #374151;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.stat-unit {
  color: #9ca3af;
}

/* 背景遮罩 */
.popup-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.1);
  z-index: 999;
}

/* 动画 */
.popup-enter-active {
  transition: all 0.2s ease;
}

.popup-leave-active {
  transition: all 0.15s ease;
}

.popup-enter-from {
  opacity: 0;
  transform: translateY(-8px) scale(0.95);
}

.popup-leave-to {
  opacity: 0;
  transform: translateY(-4px) scale(0.98);
}

/* 响应式设计 */
@media (max-width: 640px) {
  .pagination-basic {
    gap: 1px;
    padding: 3px 2px;
  }

  .pagination-btn {
    min-width: 28px;
    height: 28px;
    font-size: 12px;
  }

  .page-info {
    font-size: 12px;
    min-width: 35px;
  }

  .more-options-popup {
    left: -10px;
    min-width: auto;
  }

  .popup-content {
    padding: 8px;
  }

  .option-group {
    margin-bottom: 8px;
  }
}

/* 深色模式支持 */
@media (prefers-color-scheme: dark) {
  .pagination-basic {
    background: #1f2937;
    border-color: #374151;
  }

  .pagination-btn {
    color: #9ca3af;
  }

  .pagination-btn:hover:not(:disabled) {
    background: #374151;
    color: #e5e7eb;
  }

  .more-options-popup {
    background: #1f2937;
    border-color: #374151;
  }

  .option-label {
    color: #e5e7eb;
  }

  .jump-input {
    background: #374151;
    border-color: #4b5563;
    color: #e5e7eb;
  }

  .size-btn,
  .quick-btn {
    background: #374151;
    border-color: #4b5563;
    color: #9ca3af;
  }

  .stats-info {
    background: #374151;
  }
}
</style>
